using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

using LegendemuDB;
using LegendemuDB.Actors;
using LegendemuLogin;
using LegendemuMap;
using LegendemuLib;

namespace DB_Editor
{
    public partial class fr_Main : Form
    {
        public UserDB userDB;
        public ActorDB charDB;

        private uint[] currentcharlist = null;
        private User currentuser = null;
        private ActorPC currentchar = null;

        public Dictionary<int, CharServer> charServerList = new Dictionary<int, CharServer>();
        
        public fr_Main()
        {
            InitializeComponent();
        }

        private void fr_Main_Load(object sender, EventArgs e)
        {
            Console.WriteLine("test");
            if (!System.IO.File.Exists("Config\\login.config") ||
                !System.IO.File.Exists("Config\\map.config") ||
                !System.IO.File.Exists("Config\\worlds.config"))
            {
                MessageBox.Show("Please put this application under saga's folder!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                Dispose();
                return;
            }
            this.Show();
            Application.DoEvents();
            if (!StartDatabase() || !StartUserDatabase() || !StartWorldDatabase())
                status.Text = "Failed to connect to database!";
            else
                status.Text = "Successfully connected to database.";
            LegendemuDB.Items.AdditionFactory.Start("DB/additionDB.xml");           
            LegendemuDB.Items.Item.LoadItems("DB/itemDB.xml");
            LegendemuMap.Skills.SkillFactory.Start("DB/skillDB.xml");
        }

        public bool StartWorldDatabase()
        {


            foreach (WorldConfig.World world in WorldConfig.Instance.Worlds.Values)
            {
                if (!charServerList.ContainsKey(world.ID))
                {
                    ActorDB newCharDB = null; ;
                    switch (world.ifSQL)
                    {
                        case 0:
                            newCharDB = new db4oCharacterDB(world.DBHost, world.DBPort, world.DBUser, world.DBPass);
                            break;
                        case 1:
                            newCharDB = new MySQLCharacterDB(world.DBHost, world.DBPort, world.DBName, world.DBUser, world.DBPass);
                            break;
                        case 2:
                            newCharDB = new DatCharacterDB(world.Name, world.DBHost);
                            break;
                    }

                    try
                    {
                        newCharDB.Connect();
                    }
                    catch (Exception)
                    {
                        switch (world.ifSQL)
                        {
                            case 0:
                                MessageBox.Show("Error: Cannot connect to world db server " + world.DBHost + ":" + world.DBPort + " with username: " + world.DBUser + " and pass: " + world.DBPass, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                                break;
                            case 1:
                                MessageBox.Show("Error: Cannot connect to world db server " + world.DBHost + ":" + world.DBPort + " with username: " + world.DBUser + " and pass: " + world.DBPass, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                                break;
                        }
                        return false;
                    }
                    charServerList.Add(world.ID, new CharServer(world.Name, 0, 0, (byte)world.ID, newCharDB));
                }
                else
                {
                    Console.WriteLine("ERROR, cannot add world: " + world.Name + " with ID: " + world.ID + " reason: worldID is already taken");
                    return false;
                }
            }

            return true;
        }

        public bool StartUserDatabase()
        {
            
            switch (LoginConfig.Instance.ifSQL)
            {
                case 0:
                    userDB = new db4oUserDB(LoginConfig.Instance.DBHost, LoginConfig.Instance.DBPort, LoginConfig.Instance.DBUser, LoginConfig.Instance.DBPass);
                    break;
                case 1:
                    userDB = new MYSQLUserDB(LoginConfig.Instance.DBHost, LoginConfig.Instance.DBPort, LoginConfig.Instance.DBName, LoginConfig.Instance.DBUser, LoginConfig.Instance.DBPass);
                    break;
                case 2:
                    userDB = new DatUserDB(LoginConfig.Instance.DBHost);
                    break;
                case 3:
                    userDB = new MSSQLUserDB(LoginConfig.Instance.DBHost, LoginConfig.Instance.DBPort, LoginConfig.Instance.DBName, LoginConfig.Instance.DBUser, LoginConfig.Instance.DBPass);
                    break;
            }
            if (!userDB.Connect())
            {
                switch (LoginConfig.Instance.ifSQL)
                {
                    case 0:
                        MessageBox.Show("Error: Cannot connect to db server " + LoginConfig.Instance.DBHost + ":" + LoginConfig.Instance.DBPort + " with username: " + LoginConfig.Instance.DBUser + " and pass: " + LoginConfig.Instance.DBPass, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);

                        break;
                    case 1:
                        MessageBox.Show("Error: Cannot connect to db server " + LoginConfig.Instance.DBHost + ":" + LoginConfig.Instance.DBPort + " with username: " + LoginConfig.Instance.DBUser + " and pass: " + LoginConfig.Instance.DBPass, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        break;
                }
                return false;
            }           
            return true;
        }

        public bool StartDatabase()
        {
            switch (MapConfig.Instance.ifSQL)
            {
                case 0:
                    charDB = new db4oCharacterDB(MapConfig.Instance.DBHost, MapConfig.Instance.DBPort, MapConfig.Instance.DBUser, MapConfig.Instance.DBPass);
                    break;
                case 1:
                    charDB = new MySQLCharacterDB(MapConfig.Instance.DBHost, MapConfig.Instance.DBPort, MapConfig.Instance.DBName, MapConfig.Instance.DBUser, MapConfig.Instance.DBPass);
                    break;
                case 2:
                    charDB = new DatCharacterDB(MapConfig.Instance.WorldName, MapConfig.Instance.DBHost);
                    break;
                case 3:
                    charDB = new MSSQLCharacterDB(MapConfig.Instance.DBHost, MapConfig.Instance.DBPort, MapConfig.Instance.DBName, MapConfig.Instance.DBUser, MapConfig.Instance.DBPass);
                    break;
            }
            try
            {
                charDB.Connect();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message + ex.StackTrace, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            return true;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            status.Text = "Connecting database...";
            Application.DoEvents();
            if (!StartDatabase() || !StartUserDatabase() || !StartWorldDatabase())
                status.Text = "Failed to connect to database!";
            else
                status.Text = "Successfully connected to database.";
        }

        private void button2_Click(object sender, EventArgs e)
        {
            currentchar = null;
            currentuser = null;
            
            currentuser = userDB.GetUser(textBox1.Text);
            if (currentuser == null)
            {
                MessageBox.Show("This account do not exist!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            else
            {
                TreeNode node = treeView1.Nodes["Account"].Nodes["chars"];
                node.Nodes.Clear();
                currentcharlist = charDB.GetCharIDs(currentuser.AccountID);
                if (currentcharlist != null)
                {
                    foreach (uint i in currentcharlist)
                    {
                        ActorPC pc = charDB.GetChar(i);
                        TreeNode newnode = new TreeNode(pc.name);
                        node.Nodes.Add(newnode);
                    }
                }
                else
                {
                    foreach (uint i in currentuser.chars[1])
                    {
                        ActorPC pc = charDB.GetChar(i);
                        if (pc == null) continue;
                        TreeNode newnode = new TreeNode(pc.name);
                        node.Nodes.Add(newnode);
                    }
                }
            }
        }

        private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
        {
            switch (e.Node.Name)
            {
                case "AccountInfo":
                    if (currentuser != null)
                    {
                        property.SelectedObject = currentuser;
                    }
                    break;
                case "Account":
                    break;
                default:
                    if (e.Node.Parent.Name == "chars")
                    {
                        uint id;
                        if (currentcharlist != null)
                            id = currentcharlist[e.Node.Index];
                        else
                            id = currentuser.chars[1][e.Node.Index];
                        ActorPC pc = charDB.GetChar(id);
                        currentchar = pc;
                        property.SelectedObject = pc;
                        return;
                    }
                    property.SelectedObject = null;
                    break;
            }
        }

        private void button3_Click(object sender, EventArgs e)
        {
            if (currentuser != null)
                userDB.WriteUser(currentuser);
            if (currentchar != null)
                charDB.SaveChar(currentchar);
        }

        private void button4_Click(object sender, EventArgs e)
        {
            LegendemuMap.Skills.Skill skill = LegendemuMap.Skills.SkillFactory.GetSkill(uint.Parse(textBox2.Text));
            property2.SelectedObject = skill;
        }

    }
}